/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = frcmd_server_l7.c                                  */
/*  NOTE      =                                                    */
/*  DATE      = 2014/12/29 by geyh                                 */
/*******************************************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <sys/types.h>

#include "frcomm.h"
#include "frmem.h"
#include "frlog.h"
#include "frame.h"
#include "client.pb.h"
#include "frconfig.h"
#include "conntrack.h"
#include "frproto_mng.h"
#include "frproto_l7default.h"
#include "frame_params.h"
#include "frcmd_server.h"
#include "frcmd_server_l7.h"
#include "frame_cfg.h"
#include "frxml_parse.h"

#define     ARR_L7_SET_MAX_LEN       256
#define     ARR_MODULE_SET_MAX_LEN   256
#define     ARR_FILE_TMP_MAX_LEN     128
#define     ARR_SYS_CMD_MAX_LEN      128

#define     CMD_MODULE_ADD           0
#define     CMD_MODULE_DEL           1
#define     CMD_MODULE_CLEAR         2
#define     CMD_MODULE_UPLOAD        3
#define     CMD_MODULE_REMOVE        4

#define     MODULE_IS_STOP           0     
#define     MODULE_IS_START          1  

#define     MODULE_PROTO_XPATH_ROOT  "/"
#define     MODULE_PROTO_XPATH_KEY  "module"
#define     MODULE_PROTO_XPATH_PROTO "l7_proto"

#define     FILE_START_MODULEFILE   "../conf/start_module.xml"
#define     START_MODULE_XPATH_ROOT "/start_modules"
#define     START_MODULE_KEY_MODULE "module"

typedef struct __info_action {
    int i_action;  //(0:add/1:del/2:clear/3:upload)
    int i_value;
    int l7_proto;
    int i_start;
    char *p_value;
    char *p_all_value;
} Info_action;

typedef struct __l7info_action {
    int i_action;  //(0:add/1:del)
    int ip_proto;
    int ip;
    char *port;
    int l7_proto;
} L7info_action;

FR_STATIC Frlist_header g_st_l7_header;
FR_STATIC Frlist_header g_st_l7_default_header;
FR_STATIC Frlist_header g_st_module_header;
FR_STATIC Frlist_header g_st_module_cache;

FR_STATIC pthread_spinlock_t  g_spin_command_lock;

FR_STATIC int __module_add_cache(char *p_all_value, int i_l7_proto, char *p_path_bin, int i_start);
FR_STATIC void __module_del_cache(int i_l7_proto);
FR_STATIC Info_action* __module_cache_find(int i_l7_proto);
FR_STATIC int __frmodule_add_start_file(int i_l7_proto);

/*******************************************************************************
*  FUNC     :  释放链表节点
*  ARGS     :  Frlist_node* node   需要释放的链表节点
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __cmd_info_node_free(Frlist_node* node)
{
    Info_action *p_st_info = NULL;

    if (node == NULL || node->data == NULL)
        return;
    p_st_info = (Info_action *)node->data;

    if (p_st_info->p_value)
        frfree(p_st_info->p_value);
    if (p_st_info->p_all_value)
        frfree(p_st_info->p_all_value);
    frfree(p_st_info);
    return;
}

/*******************************************************************************
*  FUNC     :  释放链表节点
*  ARGS     :  Frlist_node* node   需要释放的链表节点
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC void __l7info_node_free(Frlist_node* node)
{
    L7info_action *p_st_info = NULL;

    if (node == NULL || node->data == NULL)
        return;
    p_st_info = (L7info_action *)node->data;

    if (p_st_info->port)
        frfree(p_st_info->port);
    frfree(p_st_info);
    return;
}

/*******************************************************************************
*  FUNC     :  从module.xml里取得协议号
*  ARGS     :  p_path_bin       module.xml的路径
*           :  p_l7_proto
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_get_proto(const char *p_path_bin, int *p_l7_proto)
{
    char *p_value = NULL;

    if (p_path_bin == NULL)
        return FR_FAIL;

    if (frxml_get2doc_prop_string(p_path_bin, MODULE_PROTO_XPATH_ROOT, MODULE_PROTO_XPATH_KEY, MODULE_PROTO_XPATH_PROTO, &p_value) != FR_SUCC)
        return FR_FAIL;

    *p_l7_proto = atoi(p_value);
    frfree(p_value);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  把模块协议号和模块路径拼接起来
*  ARGS     :  p_path_bin       module.xml的路径
*           :  i_proto          模块协议号
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_make_all_value(const char *p_path_bin, int i_proto, char **pp_all_value)
{
    char *p_all_value = NULL;
    int i_all = 0;

    if (p_path_bin == NULL)
        return FR_FAIL;

    //all = [proto] path
    i_all = strlen(p_path_bin) + 10;
    p_all_value = (char *) frmalloc(i_all + 1);
    if (p_all_value == NULL)
        return FR_FAIL;

    snprintf(p_all_value, i_all + 1, "[%d] %s", i_proto, p_path_bin);
    *pp_all_value = p_all_value;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  把拼接的信息转换为模块协议号和模块路径
*  ARGS     :  p_path_bin       module.xml的路径
*           :  i_proto          模块协议号
*  RTN      :  void
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_parse_all_value(char *p_all_value, int *p_i_proto, char **pp_path_bin)
{
    char *p_path_bin = NULL;
    char *p_tmp = NULL;
    int i_l7_proto = 0;

    if (p_all_value == NULL || *p_all_value == '\0' || p_i_proto == NULL)
        return FR_FAIL;

    p_tmp = strchr(p_all_value, '[');
    if (p_tmp == NULL)
        return FR_FAIL;

    i_l7_proto = atoi(p_tmp+1);

    p_tmp = strchr(p_tmp, ']');
    if (p_tmp == NULL)
        return FR_FAIL;

    p_path_bin = frstrdup(p_tmp + 1);
    if (p_path_bin == NULL)
        return FR_FAIL;

    frtrim(p_path_bin);

    *p_i_proto = i_l7_proto;
    *pp_path_bin = p_path_bin;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做l7命令操作(对应server_protocols)  add/del/clear
*  ARGS     :  l7_settings      L7命令
*           :  i_action         对应操作
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __do_l7_cmd(L7Setting *l7_settings, int i_action)
{
    Frlist_node *p_st_new = NULL;
    L7info_action *p_st_info_tmp;

    p_st_info_tmp = (L7info_action *) frmalloc(sizeof(L7info_action));
    if (p_st_info_tmp == NULL)
        return FR_FAIL;

    memset(p_st_info_tmp, 0x00, sizeof(L7info_action));

    p_st_info_tmp->i_action = i_action;
    if (l7_settings)
    {
        p_st_info_tmp->ip_proto = l7_settings->ip_proto();
        p_st_info_tmp->ip = l7_settings->ip();
        p_st_info_tmp->port = frstrdup(l7_settings->port().c_str());
        p_st_info_tmp->l7_proto = l7_settings->l7_proto();
    }

    pthread_spin_lock(&g_spin_command_lock);

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        if (p_st_info_tmp->port)
            frfree(p_st_info_tmp->port);
        frfree(p_st_info_tmp);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_l7_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做l7命令提交(对应server_protocols)
*  ARGS     :  p_filename       操作的文件
*           :  p_st_info        L7信息
*           :  pp_result        错误信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __do_l7_commit_detail(char *p_filename, L7info_action *p_st_info, char **pp_result)
{
    char arr_l7_set[ARR_L7_SET_MAX_LEN];
    int i_ret = FR_SUCC;

    if (p_st_info == NULL || p_filename == NULL)
    {
        *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
        return FR_FAIL;
    }

    //add
    if (p_st_info->i_action == 0)
    {
        snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s:%s-%s:%d"
               , p_st_info->ip_proto?FR_L4PROTO2STR(p_st_info->ip_proto):"any"
               , int_ntoa(p_st_info->ip)
               , p_st_info->port
               , p_st_info->port
               , p_st_info->l7_proto);
    }
    else if (p_st_info->i_action == 1)
    {
        snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s:%s"
               , p_st_info->ip_proto?FR_L4PROTO2STR(p_st_info->ip_proto):"any"
               , int_ntoa(p_st_info->ip)
               , p_st_info->port);
    }

    switch (p_st_info->i_action)
    {
        //添加/删除
        case 0:
        case 1:
        {
            Frlist_header *p_st_header = NULL;
            Frvar_field *p_st_field_tmp = NULL;
            Frlist_node *p_st_tmp = NULL;

            i_ret = frxml_get_string_list(p_filename, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS, APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS, &p_st_header);
            if (i_ret != FR_SUCC)
            {
                *pp_result = frstrdup(ERR_XML_GET);
                return FR_FAIL;
            }

            if (frlist_size(p_st_header) == 0)
            {
                if (p_st_info->i_action == 0)
                    i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS, APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS, arr_l7_set);
                frxml_free_list(&p_st_header);
                if (i_ret != FR_SUCC)
                    *pp_result = frstrdup(ERR_XML_INSERT);
                return i_ret;
            }

            p_st_tmp = FRLIST_FIRST_NODE(p_st_header);
            while(p_st_tmp)
            {
                p_st_field_tmp = (Frvar_field*)FRLIST_GET_NODE_DATA(p_st_tmp);
                if (p_st_field_tmp)
                {
                    //检索信息是否需要修改
                    if (strncmp(p_st_field_tmp->field_value.p_value, arr_l7_set, strlen(arr_l7_set)) == 0)
                    {
                        //找到相同的协议，删除之前的协议
                        i_ret = frxml_del2doc_one_cont(p_filename, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS, APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS, p_st_field_tmp->field_value.p_value);
                        if (i_ret != FR_SUCC)
                        {
                            frxml_free_list(&p_st_header);
                            *pp_result = frstrdup(ERR_XML_DEL);
                            return FR_FAIL;
                        }

                        //若是添加，添加新的协议
                        if (p_st_info->i_action == 0)
                            i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS, APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS, arr_l7_set);
                        if (i_ret != FR_SUCC)
                            *pp_result = frstrdup(ERR_XML_INSERT);

                        frxml_free_list(&p_st_header);
                        return i_ret;
                    }
                }
                p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
            }
            frxml_free_list(&p_st_header);
            //找不到相同的协议节点，若需要添加，则添加此节点
            if (p_st_info->i_action == 0)
            {
                i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS, APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS, arr_l7_set);
                if (i_ret != FR_SUCC)
                {
                    *pp_result = frstrdup(ERR_XML_INSERT);
                    return FR_FAIL;
                }
            }

            return i_ret;
        }
        //清空
        case 2:
            i_ret = frxml_del2doc_all_cont(p_filename, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS, APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS);
            if (i_ret != FR_SUCC)
                *pp_result = frstrdup(ERR_XML_DEL);
            break;
        default:
            *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
            return FR_FAIL;
    }
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  根据prepare列表(对应server_protocols)，做l7命令提交
*  ARGS     :  pp_result        错误信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_commit(char **pp_result)
{
    L7info_action *p_st_info_tmp = NULL;
    Frlist_node *p_st_tmp = NULL;
    char arr_backup[1024];
    int i_ret = 0;

    pthread_spin_lock(&g_spin_command_lock);

    if (frlist_size(&g_st_l7_header) == 0)
    {
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_SUCC;
    }
    //先将配置文件拷贝到临时文件，不直接操作配置文件
    snprintf(arr_backup, sizeof(arr_backup), "%s_l7", APM_CFG_FILENAME_ANALYZER);
    if (frcopy_file(APM_CFG_FILENAME_ANALYZER, arr_backup) != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_CONFIG_FAILED);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }

    p_st_tmp = FRLIST_FIRST_NODE(&g_st_l7_header);
    while(p_st_tmp)
    {
        p_st_info_tmp = (L7info_action*)FRLIST_GET_NODE_DATA(p_st_tmp);
        if (p_st_info_tmp)
        {
            //每条命令做一次
            i_ret = __do_l7_commit_detail(arr_backup, p_st_info_tmp, pp_result);
            if (i_ret != FR_SUCC)
            {
                pthread_spin_unlock(&g_spin_command_lock);
                return FR_FAIL;
            }
        }
        p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
    }
    frlist_remove_all(&g_st_l7_header, __l7info_node_free);

    //将临时文件拷贝到实际配置文件
    if (frcopy_file(arr_backup, APM_CFG_FILENAME_ANALYZER) != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_CONFIG_FAILED);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    remove(arr_backup);

    //重新读取L7配置
    i_ret = frproto_cfg_load(FR_YES);
    if (i_ret != FR_SUCC)
    {
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }

    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  清空所有的L7规则
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_clear_all(char **pp_result)
{
    int i_ret = 0;
    pthread_spin_lock(&g_spin_command_lock);
    frlist_remove_all(&g_st_l7_header, __l7info_node_free);
    pthread_spin_unlock(&g_spin_command_lock);

    i_ret = frxml_del2doc_all_cont(APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_SERVER_PROTOCOLS
            , APM_CFG_ANALYZER_KEY_SERVER_PROTOCOLS);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_XML_DEL);
        return FR_FAIL;
    }

    //重新读取L7配置
    i_ret = frproto_cfg_load(FR_YES);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_L7DEFAULT_RELOAD);
        return FR_FAIL;
    }
    FRLOG_INFO_DETAIL("L7 clear all");
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  回滚prepare列表的操作(对应server_protocols)
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_rollback(void)
{
    pthread_spin_lock(&g_spin_command_lock);
    frlist_remove_all(&g_st_l7_header, __l7info_node_free);
    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  L7_default的操作 add/delete/clear
*  ARGS     :  p_st_info        L7_default信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __do_l7_default_command(char *p_filename, Info_action *p_st_info, char **pp_result)
{
    char arr_l7_set[ARR_L7_SET_MAX_LEN];
    int i_ret = FR_SUCC;

    if (p_st_info == NULL)
    {
        *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
        return FR_FAIL;
    }

    if (p_st_info->p_value)
        snprintf(arr_l7_set,sizeof(arr_l7_set),"%s:%s"
                ,p_st_info->i_value?FR_L4PROTO2STR(p_st_info->i_value):"any",p_st_info->p_value);
    else
        snprintf(arr_l7_set,sizeof(arr_l7_set),"%s"
                ,p_st_info->i_value?FR_L4PROTO2STR(p_st_info->i_value):"any");

    switch (p_st_info->i_action)
    {
        //添加/删除
        case 0:
        case 1:
        {
            Frlist_header *p_st_header = NULL;
            Frvar_field *p_st_field_tmp = NULL;
            Frlist_node *p_st_tmp = NULL;

            i_ret = frxml_get_string_list(p_filename, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
                                        , APM_CFG_ANALYZER_KEY_DEFAULT, &p_st_header);
            if (i_ret != FR_SUCC)
            {
                *pp_result = frstrdup(ERR_XML_GET);
                return FR_FAIL;
            }

            if (frlist_size(p_st_header) == 0)
            {
                if (p_st_info->i_action == 0)
                    i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
                                            , APM_CFG_ANALYZER_KEY_DEFAULT, arr_l7_set);
                frxml_free_list(&p_st_header);
                if (i_ret != FR_SUCC)
                {
                    *pp_result = frstrdup(ERR_XML_INSERT);
                    return FR_FAIL;
                }
                return FR_SUCC;
            }

            p_st_tmp = FRLIST_FIRST_NODE(p_st_header);
            while(p_st_tmp)
            {
                p_st_field_tmp = (Frvar_field*)FRLIST_GET_NODE_DATA(p_st_tmp);
                if (p_st_field_tmp)
                {
                    const char *p_proto = p_st_info->i_value?FR_L4PROTO2STR(p_st_info->i_value):"any";
                    //检索信息是否需要修改
                    if (strncmp(p_st_field_tmp->field_value.p_value, p_proto, strlen(p_proto)) == 0)
                    {
                        //找到相同的协议，删除之前的协议
                        i_ret = frxml_del2doc_one_cont(p_filename, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
                                        , APM_CFG_ANALYZER_KEY_DEFAULT, p_st_field_tmp->field_value.p_value);
                        if (i_ret != FR_SUCC)
                        {
                            *pp_result = frstrdup(ERR_XML_DEL);
                            frxml_free_list(&p_st_header);
                            return FR_FAIL;
                        }
                        //若是添加，添加新的协议
                        if (p_st_info->i_action == 0)
                            i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
                                        , APM_CFG_ANALYZER_KEY_DEFAULT, arr_l7_set);

                        frxml_free_list(&p_st_header);
                        if (i_ret != FR_SUCC)
                        {
                            *pp_result = frstrdup(ERR_XML_INSERT);
                            return FR_FAIL;
                        }
                        return FR_SUCC;
                    }
                }
                p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
            }
            //找不到相同的协议节点，若需要添加，则添加此节点
            if (p_st_info->i_action == 0)
                i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
                                        , APM_CFG_ANALYZER_KEY_DEFAULT, arr_l7_set);

            frxml_free_list(&p_st_header);
            if (i_ret != FR_SUCC)
            {
                *pp_result = frstrdup(ERR_XML_INSERT);
                return FR_FAIL;
            }
            return FR_SUCC;
        }
        //清空
        case 2:
            i_ret = frxml_del2doc_all_cont(p_filename, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
                                        , APM_CFG_ANALYZER_KEY_DEFAULT);
            if (i_ret != FR_SUCC)
            {
                *pp_result = frstrdup(ERR_XML_DEL_ALL);
                return FR_FAIL;
            }
            break;
        default:
            *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
            return FR_FAIL;
    }
    return i_ret;
}

/*******************************************************************************
*  FUNC     :  L7_default的提交操作
*  ARGS     :  pp_result        错误信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_default_commit(char **pp_result)
{
    Info_action *p_st_info_tmp = NULL;
    Frlist_node *p_st_tmp = NULL;
    char arr_backup[1024];
    int i_ret = 0;

    pthread_spin_lock(&g_spin_command_lock);

    if (frlist_size(&g_st_l7_default_header) == 0)
    {
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_SUCC;
    }
    //先将配置文件拷贝到临时文件，不直接操作配置文件
    snprintf(arr_backup, sizeof(arr_backup), "%s_l7_default", APM_CFG_FILENAME_ANALYZER);
    if (frcopy_file(APM_CFG_FILENAME_ANALYZER, arr_backup) != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_CONFIG_FAILED);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }

    p_st_tmp = FRLIST_FIRST_NODE(&g_st_l7_default_header);
    while(p_st_tmp)
    {
        p_st_info_tmp = (Info_action*)FRLIST_GET_NODE_DATA(p_st_tmp);
        if (p_st_info_tmp)
        {
            //每条命令做一次
            i_ret = __do_l7_default_command(arr_backup, p_st_info_tmp, pp_result);
            if (i_ret != FR_SUCC)
            {
                pthread_spin_unlock(&g_spin_command_lock);
                return FR_FAIL;
            }
        }
        p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
    }
    frlist_remove_all(&g_st_l7_default_header, __cmd_info_node_free);

    //将临时文件拷贝到实际配置文件
    if (frcopy_file(arr_backup, APM_CFG_FILENAME_ANALYZER) != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_CONFIG_FAILED);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    remove(arr_backup);

    i_ret = frproto_l7default_load(FR_YES);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_L7DEFAULT_RELOAD);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    pthread_spin_unlock(&g_spin_command_lock);
    return FR_SUCC;
}


/*******************************************************************************
*  FUNC     :  清除所有的L7_default
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_default_clear_all(char **pp_result)
{
    int i_ret = 0;

    pthread_spin_lock(&g_spin_command_lock);
    frlist_remove_all(&g_st_l7_default_header, __cmd_info_node_free);
    pthread_spin_unlock(&g_spin_command_lock);

    i_ret = frxml_del2doc_all_cont(APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_L7_DEFAULT
            , APM_CFG_ANALYZER_KEY_DEFAULT);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_XML_DEL_ALL);
        return FR_FAIL;
    }
    i_ret = frproto_l7default_load(FR_YES);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_L7DEFAULT_RELOAD);
        return FR_FAIL;
    }
    FRLOG_INFO_DETAIL("L7 default clear all");
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  L7_default的回滚操作
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_default_rollback(void)
{
    pthread_spin_lock(&g_spin_command_lock);
    frlist_remove_all(&g_st_l7_default_header, __cmd_info_node_free);
    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  L7_default的命令
*  ARGS     :  p_command        命令
*           :  pp_result        错误信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7_cmd(Command *p_command, char **pp_result)
{
    L7Command l7_cmd = p_command->l7_cmd();
    int i_ret = 0;

    if (!l7_cmd.has_action())
        goto err;

    if (strncasecmp(l7_cmd.action().c_str(), "add", strlen("add")) == 0)
    {
        frdbg("__do_l7_add start\n");
        L7Setting l7_settings = l7_cmd.l7_settings(0);
        i_ret = __do_l7_cmd(&l7_settings, 0);
    }
    else if (strncasecmp(l7_cmd.action().c_str(), "del", strlen("del")) == 0)
    {
        frdbg("__do_l7_del start\n");
        L7Setting l7_settings = l7_cmd.l7_settings(0);
        i_ret = __do_l7_cmd(&l7_settings, 1);
    }
    else if (strncasecmp(l7_cmd.action().c_str(), "clear", strlen("clear")) == 0)
    {
        frdbg("__do_l7_clear start\n");
        i_ret = __do_l7_cmd(NULL, 2);
    }
    else
        goto err;

    if (i_ret != FR_SUCC)
        *pp_result = frstrdup(ERR_MALLOC_FAILED);

    return i_ret;

err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  L7_default的添加命令
*  ARGS     :  ip_proto
*           :  l7_proto
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __l7_default_add(int ip_proto, int l7_proto)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;
    char *p_l7_proto = NULL;

    p_st_info_tmp = (Info_action *) frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        return FR_FAIL;

    p_l7_proto = (char *)frmalloc(20);
    if (p_l7_proto == NULL)
    {
        frfree(p_st_info_tmp);
        return FR_FAIL;
    }
    snprintf(p_l7_proto, 20, "%d", l7_proto);

    p_st_info_tmp->i_action = 0;
    p_st_info_tmp->p_value = p_l7_proto;
    p_st_info_tmp->i_value = ip_proto;

    pthread_spin_lock(&g_spin_command_lock);

//    if (frlist_size(&g_st_l7_default_header) > 0)
//    {
//        //查找列表中是否已存在该地址
//        Frlist_node *p_st_find = NULL;
//        p_st_find = frlist_find(&g_st_l7_default_header, p_st_info_tmp, __value_compare);
//        if (p_st_find)
//        {
//            frfree(p_st_info_tmp->p_value);
//            frfree(p_st_info_tmp);
//            pthread_spin_unlock(&g_spin_command_lock);
//            return FR_SUCC;
//        }
//    }
    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp->p_value);
        frfree(p_st_info_tmp);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_l7_default_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  L7_default的删除命令
*  ARGS     :  ip_proto
*           :  l7_proto
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __l7_default_del(int ip_proto)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;

    //获取l7_settings
    p_st_info_tmp = (Info_action *)frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        return FR_FAIL;

    p_st_info_tmp->i_action = 1;
    p_st_info_tmp->p_value = NULL;
    p_st_info_tmp->i_value = ip_proto;

    pthread_spin_lock(&g_spin_command_lock);

//    if (frlist_size(&g_st_l7_default_header) > 0)
//    {
//        //查找列表中是否已存在该地址
//        Frlist_node *p_st_find = NULL;
//        p_st_find = frlist_find(&g_st_l7_default_header, p_st_info_tmp, __value_compare);
//        if (p_st_find)
//        {
//            frfree(p_st_info_tmp);
//            pthread_spin_unlock(&g_spin_command_lock);
//            return FR_SUCC;
//        }
//    }
    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_l7_default_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  L7_default的清除命令
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __l7_default_clear(void)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;

    p_st_info_tmp = (Info_action *)frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        return FR_FAIL;

    p_st_info_tmp->i_action = 2;
    p_st_info_tmp->p_value = NULL;
    p_st_info_tmp->i_value = 0;

    pthread_spin_lock(&g_spin_command_lock);

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_l7_default_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做L7_default的命令
*  ARGS     :  p_command            命令内容
*           :  pp_result            错误信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_l7default_cmd(Command *p_command, char **pp_result)
{
    L7Default l7_default = p_command->l7_default();
    L7Setting l7_settings;
    int i_ret = 0;

    if (!l7_default.has_action())
        goto err;

    if (strncasecmp(l7_default.action().c_str(), "add", strlen("add")) == 0)
    {
        frdbg("__do_l7default_add start\n");
        if (l7_default.l7_settings_size() == 0)
            goto err;
        l7_settings = l7_default.l7_settings(0);
        i_ret = __l7_default_add(l7_settings.ip_proto(),l7_settings.l7_proto());
    }
    else if (strncasecmp(l7_default.action().c_str(), "del", strlen("del")) == 0)
    {
        frdbg("__do_l7default_del start\n");
        if (l7_default.l7_settings_size() == 0)
            goto err;
        l7_settings = l7_default.l7_settings(0);
        i_ret = __l7_default_del(l7_settings.ip_proto());
    }
    else if (strncasecmp(l7_default.action().c_str(), "clear", strlen("clear")) == 0)
    {
        frdbg("__l7_default_clear start\n");
        i_ret = __l7_default_clear();
    }
    else
        goto err;

    if (i_ret != FR_SUCC)
        *pp_result = frstrdup(ERR_MALLOC_FAILED);

    return i_ret;
err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  做模块提交的写文件操作
*  ARGS     :  p_filename       文件名
*           :  p_st_info        操作
*           :  p_st_header      链表头(把操作存起来)
*           :  pp_result        失败信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __do_module_command(char *p_filename, Info_action *p_st_info
                                , Frlist_header *p_st_header, char **pp_result)
{
    int i_ret = FR_SUCC;
    Info_action *p_st_info_tmp = NULL;
    Frlist_node *p_st_new = NULL;

    if (p_st_info == NULL || p_filename == NULL || p_st_header == NULL)
    {
        *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
        return FR_FAIL;
    }

    p_st_info_tmp = (Info_action *) frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
    {
        *pp_result = frstrdup(ERR_MALLOC_FAILED);
        return FR_FAIL;
    }

    memset(p_st_info_tmp, 0x00, sizeof(Info_action));

    switch (p_st_info->i_action)
    {
        //添加
        case CMD_MODULE_UPLOAD:
            p_st_info_tmp->i_action = CMD_MODULE_UPLOAD;
            p_st_info_tmp->l7_proto = p_st_info->l7_proto;
            p_st_info_tmp->p_value = frstrdup(p_st_info->p_value);
            p_st_info_tmp->p_all_value = frstrdup(p_st_info->p_all_value);
            
            {
                Info_action *p_st_info_cache = NULL;
                p_st_info_cache = __module_cache_find(p_st_info_tmp->l7_proto);
                if (p_st_info_cache)
                {
                    frxml_del2doc_one_cont(p_filename, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, p_st_info_cache->p_all_value);
                    __module_del_cache(p_st_info_tmp->l7_proto);
                }
                i_ret = frxml_insert2doc_content(p_filename, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, p_st_info_tmp->p_all_value);
            }
            __module_add_cache(p_st_info->p_all_value, p_st_info->l7_proto, p_st_info->p_value, MODULE_IS_STOP);
            break;
        //启用
        case CMD_MODULE_ADD:
            p_st_info_tmp->i_action = CMD_MODULE_ADD;
            p_st_info_tmp->l7_proto = p_st_info->l7_proto;
            //R2需要设置p_value p_all_value
            if (p_st_info->p_value)
                p_st_info_tmp->p_value = frstrdup(p_st_info->p_value);
            if (p_st_info->p_all_value)
                p_st_info_tmp->p_all_value = frstrdup(p_st_info->p_all_value);
            break;
        //删除
        case CMD_MODULE_DEL:
            p_st_info_tmp->i_action = CMD_MODULE_DEL;
            p_st_info_tmp->l7_proto = p_st_info->l7_proto;
            p_st_info_tmp->p_value = frstrdup(p_st_info->p_value);
            p_st_info_tmp->p_all_value = frstrdup(p_st_info->p_all_value);
            break;
        case CMD_MODULE_REMOVE:
            p_st_info_tmp->i_action = CMD_MODULE_REMOVE;
            p_st_info_tmp->l7_proto = p_st_info->l7_proto;
            p_st_info_tmp->p_value = frstrdup(p_st_info->p_value);
            p_st_info_tmp->p_all_value = frstrdup(p_st_info->p_all_value);
            break;
        //清空
        case CMD_MODULE_CLEAR:
            i_ret = frxml_del2doc_all_cont(p_filename, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE);
            if (i_ret != FR_SUCC)
            {
                frfree(p_st_info_tmp);
                *pp_result = frstrdup(ERR_XML_DEL);
                return FR_FAIL;
            }
            p_st_info_tmp->i_action = CMD_MODULE_CLEAR;
            p_st_info_tmp->p_all_value = NULL;
            break;
        default:
            //never happen
            frfree(p_st_info_tmp);
            *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
            return FR_FAIL;
    }
    //添加到动作链表，先做文件合并，再做module操作
    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        if (p_st_info_tmp->p_value)
            frfree(p_st_info_tmp->p_value);
        if (p_st_info_tmp->p_all_value)
            frfree(p_st_info_tmp->p_all_value);
        frfree(p_st_info_tmp);

        *pp_result = frstrdup(ERR_MALLOC_FAILED);

        return FR_FAIL;
    }
    frlist_add_tail(p_st_header, p_st_new);

    return i_ret;
}

/*******************************************************************************
*  FUNC     :  清除所有的模块
*  ARGS     :  pp_result        失败信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_module_clear_all(char **pp_result)
{
    int i_ret = 0;

    frmodule_unregister_all();

    pthread_spin_lock(&g_spin_command_lock);

    frlist_remove_all(&g_st_module_header, __cmd_info_node_free);
    frlist_remove_all(&g_st_module_cache, __cmd_info_node_free);

    i_ret = frxml_del2doc_all_cont(APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_XML_DEL);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }

    i_ret = frxml_del2doc_all_cont(FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT, START_MODULE_KEY_MODULE);
    if (i_ret != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_XML_DEL);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    pthread_spin_unlock(&g_spin_command_lock);
    FRLOG_INFO_DETAIL("module clear all");

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做模块提交
*  ARGS     :  pp_result        失败信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_module_commit(char **pp_result)
{
    Frlist_node *p_st_tmp = NULL;
    Info_action *p_st_info_tmp = NULL;
    char arr_backup[1024];
    Frlist_header st_header;
    int i_ret = 0;

    pthread_spin_lock(&g_spin_command_lock);

    if (frlist_size(&g_st_module_header) == 0)
    {
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_SUCC;
    }

    //先将配置文件拷贝到临时文件，不直接操作配置文件
    snprintf(arr_backup, sizeof(arr_backup), "%s_module", APM_CFG_FILENAME_ANALYZER);
    if (frcopy_file(APM_CFG_FILENAME_ANALYZER, arr_backup) != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_CONFIG_FAILED);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }

    //初始化操作记录链表
    frlist_header_init(&st_header);

    p_st_tmp = FRLIST_FIRST_NODE(&g_st_module_header);
    while(p_st_tmp)
    {
        p_st_info_tmp = (Info_action*)FRLIST_GET_NODE_DATA(p_st_tmp);
        if (p_st_info_tmp)
        {
            //每条命令做一次
            i_ret = __do_module_command(arr_backup, p_st_info_tmp, &st_header, pp_result);
            if (i_ret != FR_SUCC)
            {
                frlist_remove_all(&st_header, __cmd_info_node_free);
                pthread_spin_unlock(&g_spin_command_lock);
                return i_ret;
            }
        }
        p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
    }
    frlist_remove_all(&g_st_module_header, __cmd_info_node_free);

    //根据顺序做对应的添加/删除操作
    p_st_tmp = FRLIST_FIRST_NODE(&st_header);
    while(p_st_tmp)
    {
        p_st_info_tmp = (Info_action*)FRLIST_GET_NODE_DATA(p_st_tmp);
        if (p_st_info_tmp)
        {
            //添加
            if (p_st_info_tmp->i_action == CMD_MODULE_ADD)
            {
                //R2
                if (p_st_info_tmp->p_value)
                {
                    i_ret = frmodule_register_path(p_st_info_tmp->p_value);
                    if (i_ret == 2)
                    {
                        //已经添加过的模块也返回成功
                        FRLOG_WARN_DETAIL("warn, module add same module, l7=%d", p_st_info_tmp->l7_proto);
                        i_ret = FR_SUCC;
                        //*pp_result = frstrdup(ERR_ALREADY_REGISTER);
                    }
                    //解析xml失败的时候，为了保证下次解析不会出错，删除对应的value值  对应恢复备份数据的情况
                    else if (i_ret == 3)
                    {
                        frxml_del2doc_one_cont(arr_backup, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, p_st_info_tmp->p_all_value);
                        //__module_del_cache(p_st_info_tmp->l7_proto);
                        i_ret = FR_SUCC;
                    }
                    else if (i_ret == 1)
                    {
                        *pp_result = frstrdup(ERR_REGISTER_FAIL);
                        //__module_del_cache(p_st_info_tmp->l7_proto);
                    }
                    else
                    {
                        i_ret = __module_add_cache(p_st_info_tmp->p_all_value, p_st_info_tmp->l7_proto, p_st_info_tmp->p_value, MODULE_IS_START);
                        __frmodule_add_start_file(p_st_info_tmp->l7_proto);
                    }
                }
                //R3(分布式部署)
                else
                {
                    Info_action *p_st_info_cache = NULL;
                    
                    p_st_info_cache = __module_cache_find(p_st_info_tmp->l7_proto);
                    if (p_st_info_cache == NULL)
                    {
                        FRLOG_WARN_DETAIL("warn, module add failed, l7=%d", p_st_info_tmp->l7_proto);
                        p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
                        continue;
                    }
                    i_ret = frmodule_register_path(p_st_info_cache->p_value);
                    if (i_ret == 2)
                    {
                        //已经添加过的模块也返回成功
                        FRLOG_WARN_DETAIL("warn, module add same module, l7=%d", p_st_info_tmp->l7_proto);
                        i_ret = FR_SUCC;
                        //*pp_result = frstrdup(ERR_ALREADY_REGISTER);
                    }
                    //解析xml失败的时候，为了保证下次解析不会出错，删除对应的value值  对应恢复备份数据的情况
                    else if (i_ret == 3)
                    {
                        frxml_del2doc_one_cont(arr_backup, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, p_st_info_cache->p_all_value);
                        //__module_del_cache(p_st_info_tmp->l7_proto);
                        i_ret = FR_SUCC;
                    }
                    else if (i_ret == 1)
                    {
                        *pp_result = frstrdup(ERR_REGISTER_FAIL);
                        //__module_del_cache(p_st_info_tmp->l7_proto);
                    }
                    else
                    {
                        i_ret = __module_add_cache(p_st_info_cache->p_all_value, p_st_info_tmp->l7_proto, p_st_info_cache->p_value, MODULE_IS_START);
                        __frmodule_add_start_file(p_st_info_tmp->l7_proto);
                    }
                }
            }
            //删除
            else if (p_st_info_tmp->i_action == CMD_MODULE_DEL)
            {
                //R3增加协议号，使用协议号删除
                i_ret = frmodule_unregister_path(p_st_info_tmp->p_value, p_st_info_tmp->l7_proto);
                if (i_ret == 2)
                {
                    //已经卸载的模块也返回成功
                    i_ret = FR_SUCC;
                    //*pp_result = frstrdup(ERR_ALREADY_UNREGISTER);
                }
                //解析xml失败的时候，为了保证下次解析不会出错，删除对应的value值  对应恢复备份数据的情况
                else if (i_ret == 3)
                {
                    if (p_st_info_tmp->p_value)
                        frxml_del2doc_one_cont(arr_backup, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, p_st_info_tmp->p_all_value);
                    i_ret = FR_SUCC;
                }
                else if (i_ret == 1)
                    *pp_result = frstrdup(ERR_UNREGISTER_FAIL);
                    
                //启动标志设置为不启动
                {
                    Info_action *p_st_info_cache = NULL;
                    p_st_info_cache = __module_cache_find(p_st_info_tmp->l7_proto);
                    if (p_st_info_cache)
                    {
                        p_st_info_cache->i_start = MODULE_IS_STOP;
                    }
                }
                //删除xml启动列表里对应的协议号
                {
                    char arr_l7[20];
                    snprintf(arr_l7, sizeof(arr_l7), "%d", p_st_info_tmp->l7_proto);
                    frxml_del2doc_one_cont(FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT, START_MODULE_KEY_MODULE, arr_l7);
                }
            }
            else if (p_st_info_tmp->i_action == CMD_MODULE_REMOVE)
            {
                __module_del_cache(p_st_info_tmp->l7_proto);
                frxml_del2doc_one_cont(arr_backup, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, p_st_info_tmp->p_all_value);
                //删除xml启动列表里对应的协议号
                {
                    char arr_l7[20];
                    snprintf(arr_l7, sizeof(arr_l7), "%d", p_st_info_tmp->l7_proto);
                    frxml_del2doc_one_cont(FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT, START_MODULE_KEY_MODULE, arr_l7);
                }
            }
            //todo
            //跳过upload
            //清空，暂时不支持
            else
            {
                p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
                continue;
            }
            if (i_ret != FR_SUCC)
            {
                frlist_remove_all(&st_header, __cmd_info_node_free);
                pthread_spin_unlock(&g_spin_command_lock);
                frproto_l7default_load(FR_YES);
                return i_ret;
            }
        }
        p_st_tmp = FRLIST_NEXT_NODE(p_st_tmp);
    }
    frlist_remove_all(&st_header, __cmd_info_node_free);
    //将临时文件拷贝到实际配置文件
    if (frcopy_file(arr_backup, APM_CFG_FILENAME_ANALYZER) != FR_SUCC)
    {
        *pp_result = frstrdup(ERR_CONFIG_FAILED);
        pthread_spin_unlock(&g_spin_command_lock);
        frproto_l7default_load(FR_YES);
        return FR_FAIL;
    }
    remove(arr_backup);

    pthread_spin_unlock(&g_spin_command_lock);
    frproto_l7default_load(FR_YES);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做模块回滚
*  ARGS     :  pp_result        失败信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_module_rollback(void)
{
    pthread_spin_lock(&g_spin_command_lock);
    frlist_remove_all(&g_st_module_header, __cmd_info_node_free);
    pthread_spin_unlock(&g_spin_command_lock);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做模块添加
*  ARGS     :  p_path           模块路径
*           :  i_action         0:添加 1:删除
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_path_cmd(const char *p_path, int i_action)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;
    char *p_all_value = NULL;
    int i_l7_proto = 0;

    if (p_path == NULL)
        return FR_FAIL;

    if (__module_get_proto(p_path, &i_l7_proto) != FR_SUCC)
        return FR_FAIL;

    if (__module_make_all_value(p_path, i_l7_proto, &p_all_value) != FR_SUCC)
        return FR_FAIL;

    p_st_info_tmp = (Info_action *) frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
    {
        frfree(p_all_value);
        return FR_FAIL;
    }

    memset(p_st_info_tmp, 0x00, sizeof(Info_action));
    p_st_info_tmp->i_action = i_action;
    p_st_info_tmp->p_value = frstrdup(p_path);
    p_st_info_tmp->p_all_value = p_all_value;
    p_st_info_tmp->l7_proto = i_l7_proto;

    pthread_spin_lock(&g_spin_command_lock);

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp->p_value);
        frfree(p_st_info_tmp->p_all_value);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_module_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做模块清除
*  ARGS     :  p_path           模块路径
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_clear(void)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;

    p_st_info_tmp = (Info_action *) frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        return FR_FAIL;

    memset(p_st_info_tmp, 0x00, sizeof(Info_action));
    p_st_info_tmp->i_action = 2;
    p_st_info_tmp->p_value = NULL;
    p_st_info_tmp->p_all_value = NULL;
    p_st_info_tmp->l7_proto = 0;

    pthread_spin_lock(&g_spin_command_lock);

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_module_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
}

static int __module_download_upload(ModuleCommand *p_module_cmd, char **pp_result)
{
    char arr_cmd[512];
    char arr_zip[512];
    char arr_dir[512];
    char arr_module_xml[512];
    char arr_uuid[APM_UUID_SIZE];
    FILE *fp = NULL;
    int i_ret = FR_SUCC, i_status = 0;

    if (p_module_cmd == NULL || !p_module_cmd->has_l7_proto()
      || !p_module_cmd->has_mod_bin())
        goto cmd_err;

    i_ret = fruuid(arr_uuid);
    if (i_ret != FR_SUCC)
        goto serious_err;

    snprintf(arr_dir, sizeof(arr_dir), "%s/%d/%s", APM_MODULE_WORK_DIR, p_module_cmd->l7_proto(), arr_uuid);

    //创建uuid的目录
    snprintf(arr_cmd, sizeof(arr_cmd), "mkdir -p %s", arr_dir);
    system(arr_cmd);

    //将压缩文件写到uuid的目录
    snprintf(arr_zip, sizeof(arr_zip), "%s/%d.zip", arr_dir, p_module_cmd->l7_proto());
    fp = fopen(arr_zip, "w");
    if (fp == NULL)
        goto serious_err;

    fwrite(p_module_cmd->mod_bin().c_str(), p_module_cmd->mod_bin().length(), 1, fp);

    fclose(fp);

    //解压
    snprintf(arr_cmd, sizeof(arr_cmd), "unzip %s -d %s", arr_zip, arr_dir);
    i_status = system(arr_cmd);
    if (i_status == -1)
        goto unzip_err;
    else
    {
        if (!WIFEXITED(i_status))
            goto unzip_err;
        if (WEXITSTATUS(i_status))
            goto unzip_err;
    }

    //判断module.xml是否存在
    snprintf(arr_module_xml, sizeof(arr_module_xml), "%s/module.xml", arr_dir);
    if (access(arr_module_xml, R_OK) != 0)
        goto unzip_err;

    //添加到等待列表
    {
        Frlist_node *p_st_new = NULL;
        Info_action *p_st_info_tmp;
        char *p_all_value = NULL;

        if (__module_make_all_value(arr_module_xml, p_module_cmd->l7_proto(), &p_all_value) != FR_SUCC)
            return FR_FAIL;
            
        p_st_info_tmp = (Info_action *)frmalloc(sizeof(Info_action));
        if (p_st_info_tmp == NULL)
        {
            frfree(p_all_value);
            goto malloc_err;
        }
        memset(p_st_info_tmp, 0x00, sizeof(Info_action));
        p_st_info_tmp->i_action = CMD_MODULE_UPLOAD;
        p_st_info_tmp->p_value = frstrdup(arr_module_xml);
        p_st_info_tmp->p_all_value = p_all_value;
        p_st_info_tmp->l7_proto = p_module_cmd->l7_proto();
    
        pthread_spin_lock(&g_spin_command_lock);
        p_st_new = frlist_node_create(p_st_info_tmp);
        if (p_st_new == NULL)
        {
            frfree(p_st_info_tmp->p_value);
            frfree(p_st_info_tmp->p_all_value);
            pthread_spin_unlock(&g_spin_command_lock);
            goto malloc_err;
        }
        frlist_add_tail(&g_st_module_header, p_st_new);
        pthread_spin_unlock(&g_spin_command_lock);
        return FR_SUCC;
    }

    return FR_SUCC;

cmd_err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
unzip_err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
malloc_err:
    *pp_result = frstrdup(ERR_MALLOC_FAILED);
    return FR_FAIL;
serious_err:
    *pp_result = frstrdup(ERR_SERIOUS_DESTROY);
    return FR_FAIL;
}

static int __module_download_add(ModuleCommand *p_module_cmd, char **pp_result)
{
    if (p_module_cmd == NULL || !p_module_cmd->has_l7_proto())
        goto cmd_err;

    //添加到等待列表
    {
        Frlist_node *p_st_new = NULL;
        Info_action *p_st_info_tmp;

        p_st_info_tmp = (Info_action *)frmalloc(sizeof(Info_action));
        if (p_st_info_tmp == NULL)
        {
            goto malloc_err;
        }

        memset(p_st_info_tmp, 0x00, sizeof(Info_action));
        p_st_info_tmp->i_action = CMD_MODULE_ADD;
        p_st_info_tmp->l7_proto = p_module_cmd->l7_proto();

        pthread_spin_lock(&g_spin_command_lock);
        p_st_new = frlist_node_create(p_st_info_tmp);
        if (p_st_new == NULL)
        {
            pthread_spin_unlock(&g_spin_command_lock);
            goto malloc_err;
        }
        frlist_add_tail(&g_st_module_header, p_st_new);
        pthread_spin_unlock(&g_spin_command_lock);
    }

    return FR_SUCC;

cmd_err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
malloc_err:
    *pp_result = frstrdup(ERR_MALLOC_FAILED);
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  做模块删除
*  ARGS     :  p_path           模块路径
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
FR_STATIC int __module_download_del(ModuleCommand *p_module_cmd, char **pp_result)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;
    Info_action *p_st_info_cache = NULL;

    if (p_module_cmd == NULL || !p_module_cmd->has_l7_proto())
        goto cmd_err;

    p_st_info_cache = __module_cache_find(p_module_cmd->l7_proto());
    if (p_st_info_cache == NULL)
        goto already_unregister;

    p_st_info_tmp = (Info_action *) frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        goto malloc_err;

    memset(p_st_info_tmp, 0x00, sizeof(Info_action));
    p_st_info_tmp->i_action = CMD_MODULE_DEL;
    p_st_info_tmp->p_value = frstrdup(p_st_info_cache->p_value);
    p_st_info_tmp->p_all_value = frstrdup(p_st_info_cache->p_all_value);
    p_st_info_tmp->l7_proto = p_module_cmd->l7_proto();

    pthread_spin_lock(&g_spin_command_lock);

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp->p_value);
        pthread_spin_unlock(&g_spin_command_lock);
        goto malloc_err;
    }
    frlist_add_tail(&g_st_module_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
cmd_err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
malloc_err:
    *pp_result = frstrdup(ERR_MALLOC_FAILED);
    return FR_FAIL;
already_unregister:
    *pp_result = frstrdup(ERR_ALREADY_UNREGISTER);
    return FR_SUCC;
}

FR_STATIC int __module_download_remove(ModuleCommand *p_module_cmd, char **pp_result)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;
    Info_action *p_st_info_cache = NULL;

    if (p_module_cmd == NULL || !p_module_cmd->has_l7_proto())
        goto cmd_err;

    p_st_info_cache = __module_cache_find(p_module_cmd->l7_proto());
    if (p_st_info_cache == NULL)
        goto already_remove;

    p_st_info_tmp = (Info_action *) frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        goto malloc_err;

    memset(p_st_info_tmp, 0x00, sizeof(Info_action));
    p_st_info_tmp->i_action = CMD_MODULE_REMOVE;
    p_st_info_tmp->p_value = frstrdup(p_st_info_cache->p_value);
    p_st_info_tmp->p_all_value = frstrdup(p_st_info_cache->p_all_value);
    p_st_info_tmp->l7_proto = p_module_cmd->l7_proto();

    pthread_spin_lock(&g_spin_command_lock);

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp->p_value);
        pthread_spin_unlock(&g_spin_command_lock);
        goto malloc_err;
    }
    frlist_add_tail(&g_st_module_header, p_st_new);
    pthread_spin_unlock(&g_spin_command_lock);

    return FR_SUCC;
cmd_err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
malloc_err:
    *pp_result = frstrdup(ERR_MALLOC_FAILED);
    return FR_FAIL;
already_remove:
    *pp_result = frstrdup(ERR_ALREADY_REMOVE);
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  做模块命令主接口
*  ARGS     :  p_command        命令
*           :  pp_result        错误信息
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int do_module_cmd(Command *p_command, char **pp_result)
{
    ModuleCommand st_module_cmd = p_command->module_cmd();
    int i_ret = 0;

    if (!st_module_cmd.has_action())
        goto err;

    if (strncasecmp(st_module_cmd.action().c_str(), "add", strlen("add")) == 0)
    {
        FRLOG_INFO("__module_add start\n");
        //R2原逻辑
        if (st_module_cmd.has_so_path())
            i_ret = __module_path_cmd(st_module_cmd.so_path().c_str(), CMD_MODULE_ADD);
        //R3
        else
            return __module_download_add(&st_module_cmd, pp_result);
    }
    else if (strncasecmp(st_module_cmd.action().c_str(), "del", strlen("del")) == 0)
    {
        FRLOG_INFO("__module_del start\n");
        //R2原逻辑
        if (st_module_cmd.has_so_path())
            i_ret = __module_path_cmd(st_module_cmd.so_path().c_str(), CMD_MODULE_DEL);
        //R3
        else
            i_ret = __module_download_del(&st_module_cmd, pp_result);
    }
    else if (strncasecmp(st_module_cmd.action().c_str(), "upload", strlen("upload")) == 0)
    {
        FRLOG_INFO("__module_upload start\n");
        i_ret = __module_download_upload(&st_module_cmd, pp_result);
    }
    else if (strncasecmp(st_module_cmd.action().c_str(), "remove", strlen("remove")) == 0)
    {
        FRLOG_INFO("__module_remove start\n");
        i_ret = __module_download_remove(&st_module_cmd, pp_result);
    }
    else if (strncasecmp(st_module_cmd.action().c_str(), "clear", strlen("clear")) == 0)
    {
        FRLOG_INFO("__module_clear start\n");
        i_ret = __module_clear();
    }
    else
        goto err;

    return i_ret;
err:
    *pp_result = frstrdup(FRCMD_SERVER_NOT_SUPPORT);
    return FR_FAIL;
}

FR_STATIC Info_action* __module_cache_find(int i_l7_proto)
{
    Info_action *p_st_info_tmp;
    Frlist_node *p_st_node = NULL;

    p_st_node = FRLIST_FIRST_NODE(&g_st_module_cache);
    while(p_st_node)
    {
        p_st_info_tmp = (Info_action *)FRLIST_GET_NODE_DATA(p_st_node);
        if(p_st_info_tmp == NULL || p_st_info_tmp->p_all_value == NULL)
        {
            p_st_node = FRLIST_NEXT_NODE(p_st_node);
            continue;
        }
        if (p_st_info_tmp->l7_proto == i_l7_proto)
            return p_st_info_tmp;

        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }
    return NULL;
}

FR_STATIC int __module_add_cache(char *p_all_value, int i_l7_proto, char *p_path_bin, int i_start)
{
    Frlist_node *p_st_new = NULL;
    Info_action *p_st_info_tmp;

    if (p_path_bin == NULL || p_all_value == NULL)
        return FR_FAIL;

    p_st_info_tmp = __module_cache_find(i_l7_proto);
    if (p_st_info_tmp)
    {
        p_st_info_tmp->i_start = i_start;
        return FR_SUCC;
    }

    p_st_info_tmp = (Info_action *)frmalloc(sizeof(Info_action));
    if (p_st_info_tmp == NULL)
        return FR_FAIL;

    memset(p_st_info_tmp, 0x00, sizeof(Info_action));
    p_st_info_tmp->p_value = frstrdup(p_path_bin);
    p_st_info_tmp->p_all_value = frstrdup(p_all_value);
    p_st_info_tmp->l7_proto = i_l7_proto;
    p_st_info_tmp->i_start = i_start;

    p_st_new = frlist_node_create(p_st_info_tmp);
    if (p_st_new == NULL)
    {
        frfree(p_st_info_tmp);
        return FR_FAIL;
    }
    frlist_add_tail(&g_st_module_cache, p_st_new);

    return FR_SUCC;
}

FR_STATIC void __module_del_cache(int i_l7_proto)
{
    Info_action *p_st_info_tmp;
    Frlist_node *p_st_node = NULL;

    p_st_node = FRLIST_FIRST_NODE(&g_st_module_cache);
    while(p_st_node)
    {
        p_st_info_tmp = (Info_action *)FRLIST_GET_NODE_DATA(p_st_node);
        if(p_st_info_tmp == NULL || p_st_info_tmp->p_all_value == NULL)
        {
            p_st_node = FRLIST_NEXT_NODE(p_st_node);
            continue;
        }
        if (p_st_info_tmp->l7_proto == i_l7_proto)
        {
            frlist_node_free(&g_st_module_cache, p_st_node, FR_YES, __cmd_info_node_free);
            return;
        }
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }
    return;
}

#define START_MODULEFILE_CONTENT   "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<start_modules>\n</start_modules>"

FR_STATIC int __frmodule_start_module_chk(void)
{
    //判断start_module.xml是否存在
    if(access(FILE_START_MODULEFILE,0) != 0)
    {
        //不存在，认为是升级，生成start_module.xml
        FILE *fp = NULL;
        fp = fopen(FILE_START_MODULEFILE, "w");
        if (fp == NULL)
            return FR_FAIL;
        fwrite(START_MODULEFILE_CONTENT, strlen(START_MODULEFILE_CONTENT), 1, fp);
        fclose(fp);
        
        //写入已启用的协议
        {
            Frlist_header *p_lst_params = NULL;
            Frlist_node *p_st_node = NULL;
            int i_ret_fun=0;
            
            i_ret_fun = frxml_get_string_list(APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, &p_lst_params);
            if(i_ret_fun != FR_SUCC || p_lst_params == NULL || frlist_size(p_lst_params) <=0 )
            {
                if(p_lst_params)
                    frxml_free_list(&p_lst_params);
                FRLOG_WARN_DETAIL("open cfg[%s][%s][%s] fail(no data)", APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE);
                return FR_FAIL;
            }
            p_st_node = FRLIST_FIRST_NODE(p_lst_params);
            while(p_st_node)
            {
                int i_l7_proto = 0;
                char *p_path_bin = NULL;
                char arr_l7[20];
                Frvar_field *p_var_field = NULL;
        
                p_var_field =  (Frvar_field*)FRLIST_GET_NODE_DATA(p_st_node);
                
                if (__module_parse_all_value(p_var_field->field_value.p_value, &i_l7_proto, &p_path_bin) != FR_SUCC)
                {
                    FRLOG_WARN_DETAIL("cfg[%s] module_cfg[%s] error(data format error)"
                        , APM_CFG_FILENAME_ANALYZER, p_var_field->field_value.p_value);
                    p_st_node = FRLIST_NEXT_NODE(p_st_node);
                    continue;
                }
                snprintf(arr_l7, sizeof(arr_l7), "%d", i_l7_proto);
                i_ret_fun = frxml_insert2doc_content(FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT
                            , START_MODULE_KEY_MODULE, arr_l7);
                
                frfree(p_path_bin);
                p_st_node = FRLIST_NEXT_NODE(p_st_node);
            }
            frxml_free_list(&p_lst_params);
        }
    }
    return FR_SUCC;
}

FR_STATIC int __frmodule_find_start_file(int i_l7_proto)
{
    Frlist_header *p_lst_params = NULL;
    Frlist_node *p_st_node = NULL;
    Frvar_field *p_var_field = NULL;
    int i_ret_fun=0;
    
    i_ret_fun = frxml_get_string_list(FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT, START_MODULE_KEY_MODULE, &p_lst_params);
    if(i_ret_fun != FR_SUCC || p_lst_params == NULL)
    {
        if(p_lst_params)
            frxml_free_list(&p_lst_params);
        FRLOG_WARN_DETAIL("open cfg[%s][%s][%s] fail(no data)", FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT, START_MODULE_KEY_MODULE);
        return FR_FAIL;
    }
    p_st_node = FRLIST_FIRST_NODE(p_lst_params);
    while(p_st_node)
    {
        p_var_field =  (Frvar_field*)FRLIST_GET_NODE_DATA(p_st_node);
        if (p_var_field == NULL || p_var_field->em_data_type != FRSTRING
           || p_var_field->field_value.p_value == NULL
           || *(p_var_field->field_value.p_value) == '\0' )
        {
            p_st_node = FRLIST_NEXT_NODE(p_st_node);
            continue;
        }
        if (atoi(p_var_field->field_value.p_value) == i_l7_proto)
        {
            frxml_free_list(&p_lst_params);
            return FR_SUCC;
        }
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }
    frxml_free_list(&p_lst_params);
    return FR_FAIL;
}

FR_STATIC int __frmodule_add_start_file(int i_l7_proto)
{
    int i_ret_fun=0;
    char arr_l7[10];
    
    if (__frmodule_find_start_file(i_l7_proto) == FR_SUCC)
    {
        FRLOG_WARN_DETAIL("warn, module add same module, l7=%d", i_l7_proto);
        return FR_FAIL;
    }
    
    snprintf(arr_l7, sizeof(arr_l7), "%d", i_l7_proto);
    i_ret_fun = frxml_insert2doc_content(FILE_START_MODULEFILE, START_MODULE_XPATH_ROOT
                            , START_MODULE_KEY_MODULE, arr_l7);
    if (i_ret_fun != FR_SUCC)
    {
        return FR_FAIL;
    }
                
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  从配置文件中读取解析库配置
*  ARGS     :
*  RTN      :  FR_SUCC / FR_FAIL
*  NOTE     :  1. 如果增加配置，运行中更新配置文件没有问题
*           :  2. 如果有减少配置，请重新启动应用程序进行加载
*******************************************************************************/
int frmodule_cfg_load(void)
{
    Frlist_header *p_lst_params = NULL;
    Frlist_node *p_st_node = NULL;
    Frvar_field *p_var_field = NULL;
    int i_ret_fun=0;

    __frmodule_start_module_chk();

    //加载协议库
    i_ret_fun = frxml_get_string_list(APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE, &p_lst_params);
    if(i_ret_fun != FR_SUCC || p_lst_params == NULL || frlist_size(p_lst_params) <=0 )
    {
        if(p_lst_params)
            frxml_free_list(&p_lst_params);
        FRLOG_WARN_DETAIL("open cfg[%s][%s][%s] fail(no data)", APM_CFG_FILENAME_ANALYZER, APM_CFG_ANALYZER_XPATH_MODULE, APM_CFG_ANALYZER_KEY_MODULE);
        return FR_FAIL;
    }

    pthread_spin_lock(&g_spin_command_lock);
    //获取模块链表一览
    p_st_node = FRLIST_FIRST_NODE(p_lst_params);
    while(p_st_node)
    {
        int i_l7_proto = 0;
        char *p_path_bin = NULL;

        p_var_field =  (Frvar_field*)FRLIST_GET_NODE_DATA(p_st_node);
        if(p_var_field == NULL || p_var_field->em_data_type != FRSTRING
           || p_var_field->field_value.p_value == NULL
           || *(p_var_field->field_value.p_value) == '\0' )
        {
            p_st_node = FRLIST_NEXT_NODE(p_st_node);
            continue;
        }
        //取得模块协议号和模块路径
        if (__module_parse_all_value(p_var_field->field_value.p_value, &i_l7_proto, &p_path_bin) != FR_SUCC)
        {
            FRLOG_WARN_DETAIL("cfg[%s] module_cfg[%s] error(data format error)"
                , APM_CFG_FILENAME_ANALYZER, p_var_field->field_value.p_value);
            p_st_node = FRLIST_NEXT_NODE(p_st_node);
            continue;
        }
        //查找启动列表，不在启动列表的不启动模块
        if (__frmodule_find_start_file(i_l7_proto) != FR_SUCC)
        {
            __module_add_cache(p_var_field->field_value.p_value, i_l7_proto, p_path_bin, MODULE_IS_STOP);
            if (p_path_bin)
                frfree(p_path_bin);
            p_st_node = FRLIST_NEXT_NODE(p_st_node);
            continue;
        }

        if (frmodule_register_path(p_path_bin) == 0)
            //把模块信息缓存起来
            __module_add_cache(p_var_field->field_value.p_value, i_l7_proto, p_path_bin, MODULE_IS_START);

        if (p_path_bin)
            frfree(p_path_bin);
        p_st_node = FRLIST_NEXT_NODE(p_st_node);
    }
    pthread_spin_unlock(&g_spin_command_lock);
    frxml_free_list(&p_lst_params);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  初始化
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
int frcmd_server_l7_init(void)
{
    pthread_spin_init(&g_spin_command_lock, 0);

    frlist_header_init(&g_st_l7_default_header);
    frlist_header_init(&g_st_module_header);
    frlist_header_init(&g_st_l7_header);
    frlist_header_init(&g_st_module_cache);

    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  退出
*  ARGS     :
*  RTN      :  FR_SUCC (success)
*           :  FR_FAIL (failed)
*  NOTE     :
*******************************************************************************/
void frcmd_server_l7_destory(void)
{
    frlist_remove_all(&g_st_l7_default_header, __cmd_info_node_free);
    frlist_remove_all(&g_st_module_header, __cmd_info_node_free);
    frlist_remove_all(&g_st_l7_header, __l7info_node_free);
    frlist_remove_all(&g_st_module_cache, __cmd_info_node_free);

    pthread_spin_destroy(&g_spin_command_lock);
}
